﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed

#pragma once

#include "GcmpGeometryInterface.h"
#include "CurvesPositionTypes.h"
#include "LoopAxisPositionTypes.h"
#include "BoxGeometryPositionTypes.h"
#include "PointBodyPositionTypes.h"
#include "BodiesPositionTypes.h"
#include "PointPolygonPositionTypes.h"
#include "CurveBodyPositionTypes.h"
#include "Curve2dPolygonPositionTypes.h"
#include "LoopsPositionTypes.h"
#include "PolygonsPositionTypes.h"
#include "GbmpConstants.h"


namespace gcmp
{
    class Box3d;
    class Coordinate3d;
    class Box2d;
    class Vector3d;
    class Vector2d;
    class IPolygon;
    class ILine2d;
    class ICurve2d;
    class ILine3d;
    class ICurve3d;
    class ILoop;
    class IBody;
    class IPolyCurve;
    class IPlane;

    class  GCMP_GEOMETRY_INTERFACE_EXPORT AlgorithmPositionJudge
    {
    public:
        
        /// \brief  判断两条二维曲线的位置关系
        ///            （1、退化为点的重合段认为是相交；
        ///              2、有重合有相交认为是重合）
        ///
        /// \param pFirstICurve2d     第一条二维曲线
        /// \param pSeccondICurve2d   第二条二维曲线
        /// \param dDistanceEpsilon   距离容差
        /// \return   位置关系
        static CurvesPositionTypes GetPosition(const ICurve2d *pFirstICurve2d, const ICurve2d *pSeccondICurve2d, double dDistanceEpsilon = Constants::DISTANCE_ITERATION_EPS);

        
        /// \brief  判断两条三维曲线的位置关系,
        /// （1、退化为点的重合段认为是相交；
        ///   2、有重合有相交认为是重合）
        ///
        /// \param pFirstICurve3d    第一条三维曲线
        /// \param pSeccondICurve3d  第二条三维曲线
        /// \param dDistanceEpsilon   距离容差
        /// \return  位置关系
        static CurvesPositionTypes GetPosition(const ICurve3d *pFirstICurve3d, const ICurve3d *pSeccondICurve3d, double dDistanceEpsilon = Constants::DISTANCE_ITERATION_EPS);

        /// \brief 判断封闭多段线和轴线的位置关系
        ///
        /// \param pClosedPolyCurve              环
        /// \param pAxis2d                       轴线（参数范围任意）
        /// \return  位置关系
        static LoopAxisPositionTypes GetPosition(const IPolyCurve *pClosedPolyCurve, const ILine2d *pAxis2d);

        /// \brief 判断二维线和多边形的位置关系
        ///
        /// \param pCurve2d            二维线
        /// \param pPolygon            多边形
        /// \param dDistanceEpsilon    距离容差
        /// \return  位置关系
        static Curve2dPolygonPositionTypes GetPosition(const ICurve2d *pCurve2d, const IPolygon* pPolygon, double dDistanceEpsilon = Constants::DISTANCE_ITERATION_EPS);

        /// \brief 判断二维包围盒和二维曲线的位置关系
        ///
        /// \param box2d                     二维包围盒
        /// \param pCurve2d                  二维曲线
        /// \return  位置关系
        static BoxGeometryPositionTypes GetPosition(const Box2d &box2d, const ICurve2d *pCurve2d, double dDistanceEpsilon = Constants::DISTANCE_ITERATION_EPS);

        /// \brief 判断二维包围盒和多边形的位置关系
        ///        
        /// \param box2d                      二维包围盒
        /// \param pPolygon                   多边形
        /// \return 包围盒和其他几何元素的位置关系类型 BoxGeometryPositionTypes
        static BoxGeometryPositionTypes GetPosition(const Box2d &box2d, const IPolygon *pPolygon, double dDistanceEpsilon = Constants::DISTANCE_ITERATION_EPS);

        /// \brief 获取多边形和二维包围盒的原始位置关系类型
        ///
        /// \param box2d                      二维包围盒
        /// \param pPolygon                   多边形
        /// \return 位置关系，与ggp返回的枚举类型相匹配，PolygonsPositionTypes
        static PolygonsPositionTypes GetOriginPosition(const Box2d &box2d, const IPolygon *pPolygon, double dDistanceEpsilon = Constants::DISTANCE_ITERATION_EPS);

        /// \brief 判断二维包围盒和二维多段线的位置关系
        ///        
        /// \param box2d                      二维包围盒
        /// \param pPolyCurve                   二维多段线
        /// \return 包围盒和其他几何元素的位置关系类型 BoxGeometryPositionTypes
        static BoxGeometryPositionTypes GetPosition(const Box2d &rect, const IPolyCurve *pPolyCurve, double dDistEpsilon = Constants::DISTANCE_ITERATION_EPS);

        /// \brief 判断点和体的位置关系
        ///
        /// \param point,        点
        /// \param pBody         体
        /// \return  位置关系
        static PointBodyPositionTypes GetPosition(const Vector3d& point, const IBody *pBody);

        /// \brief 判断两个体的位置关系
        /// \param pFirstBody       第一个体
        /// \param pSecondBody      第二个体
        /// \param dDistanceEpsilon    距离容差
        /// \return  位置关系
        static BodiesPositionTypes GetPosition(const IBody* pFirstBody, const IBody* pSecondBody, double dDistanceEpsilon = 0.1);    

        /// \brief 判断环和环的位置关系
        /// \param pFirstLoop           第一个环
        /// \param pSecondILoop         第二个环
        /// \return  位置关系
        static LoopsPositionTypes GetPosition(const IPolyCurve *pFirstLoop, const IPolyCurve *pSecondILoop);

        /// \brief 判断多边形和多边形的位置关系
        /// \param pFirstPolygon          第一个多边形
        /// \param pSecondPolygon         第二个多边形
        /// \param dDistanceEpsilon    距离容差
        /// \return 位置关系
        static PolygonsPositionTypes GetPosition(const IPolygon *pFirstPolygon, const IPolygon *pSecondPolygon, double dDistanceEpsilon = Constants::DISTANCE_ITERATION_EPS);

        /// \brief 判断点和多边形的位置关系
        /// \param point                     点
        /// \param pPolygon                  多边形
        /// \param dDistanceEpsilon          距离容差
        /// \return  位置关系
        static PointPolygonPositionTypes GetPosition(const Vector2d &point, const IPolygon* pIPolygon, double dDistanceEpsilon = Constants::DISTANCE_ITERATION_EPS);

        /// \brief 判断三维曲线和体的位置关系
        /// \param pCurve3d                  三维曲线
        /// \param pBody                     体
        /// \param dDistanceEpsilon          距离容差
        /// \return  位置关系
        static CurveBodyPositionTypes GetPosition(const ICurve3d* pCurve3d, const IBody* pBody, double dDistanceEpsilon = Constants::DISTANCE_ITERATION_EPS);

        /// \brief  判断两条直线是否平行
        /// \param   pFirstLine3d          第一条直线
        /// \param  pSecondLine3d          第二条直线
       /// \return  平行返回true；否则返回false
        static bool IsParallel(const ILine3d* pFirstLine3d, const ILine3d* pSecondLine3d);

        /// \brief  判断点是否在平面上
        /// \param   pPlane             平面
        /// \param   point              点
        /// \param  dDistanceEpsilon    距离容差
        /// \return  点在平面上返回true；否则返回false
        static bool IsPointOnPlane(const IPlane* pPlane, const Vector3d& point, double disdDistanceEpsilontTol);


        /// \brief  检测数据是否在容差内对齐:顶点对齐到顶点，点对齐到曲线上
        ///
        /// 点与点的距离或者点到线的距离在[distEpsilon/disturbCoef, distEpsilon*disturbCoef]范围内认为没有对齐
        /// \param curves             二维曲线
        /// \param[in,out] toAlignedPts   曲线和没有对齐到该曲线上的点。输入为空数组
        /// \param[in] distEpsilon        距离容差
        /// \param[in] disturbCoef        扰动系数>1.0，默认为2.0
        /// \return  成功返回true；否则返回false
        static bool GetUnalignedPoints(const std::vector<const ICurve2d*> &curves, std::map<const ICurve2d*, std::vector<Vector2d>> &toAlignedPts, double distEpsilon, double disturbCoef = 2.0);

    };
}
